// #include<iostream>
// #include<pthread.h>
// #include<unistd.h>
// #include<string>
// #include<cstdio>
// #include<cstdlib>
// #include<vector>
// #include<cstring>
// using namespace std;

// const int thread_num=5;

// class Task
// {
//     public:
//         Task()
//         {}
//         void SetData(int x,int y)
//         {
//             datax=x;
//             datay=y;
//         }
//         int Excute()
//         {
//             return datax+datay;
//         }
//         ~Task()
//         {}
//     private:
//         int datax;
//         int datay;
// }

// class Result()
// {
//     public:
//         Result()
//         {}
//         ~Result()
//         {}
//         void SetResult(int result,std::string thread_name)
//         {
//             _result=result;
//             _thread_name=thread_name;
//         }
//         void Print()
//         {
//             cout<<_thread_name<<" run result:"<<_result<<endl;
//         }
//     private:
//         int _result;
//         std::string _thread_name;
// }

// class TheadDate : public Task
// {
//     public:
//         ThreadDate(int x,int y,const std::string &threadname)
//         :_thread_name(threadname)
//         {
//             _t.SetData(x,y);
//         }
//         std::string GetThreadName()
//         {
//             return _thread_name;
//         }
//         int run()
//         {
//             return _t.Excute();
//         }
//     private:
//         std::string _thread_name;
//         Task _t;
// }

// void *handlerTask(void *args)
// {
//     ThreadDate *td=static_cast<ThreadDate*>(args);

//     std::string name=td->GetThreadName();

//     Result *res=new Result();
//     int result=td->run();
    
//     res->SetResult(result,name);

//     delete td;

//     sleep(2);
//     return res;
// } 

// // void *handlerTask(void *args)
// // {
// //     //std::string thread_name=static_cast<char*>(args);
// //     const char *thread_name=static_cast<char*>(args);
// //     while(true)
// //     {
// //         std::cout<<"I am "<<thread_name<<endl;
// //         sleep(2);
// //     }
// //     delete[] thread_name;
// //     return nullptr;
// // } 

// //多线程创建
// //线程传参和返回值，我们可以传递级别信息，也可以传递其他对象
// int main()
// {
//     std::vector<pthread_t> threads;
//     for (int i = 0; i < threadnum; i++)
//     {
//         char threadname[64];
//         snprintf(threadname, 64, "Thread-%d", i + 1);
//         ThreadData *td = new ThreadData(10, 20, threadname);

//         pthread_t tid;
//         pthread_create(&tid, nullptr, handlerTask, td);
//         threads.push_back(tid);
//     }
//     std::vector<Result*> result_set;
//     void *ret = nullptr;
//     for (auto &tid : threads)
//     {
//         pthread_join(tid, &ret);
//         result_set.push_back((Result*)ret);
//     }

//     for(auto & res : result_set)
//     {
//         res->Print();
//         delete res;
//     }
// }










// // std::string ToHex(pthread_t tid)
// // {
// //     char id[64];
// //     snprintf(id,sizeof(id),"0x%lx",tid);
// //     return id;
// // }
// // //新线程
// // // void* threadrun(void* arg)
// // // {
// // //     std::string thread_name=(char*)arg;
// // //     int cnt=5;
// // //     while(cnt)
// // //     {
// // //         cout<<"thread name:"<<thread_name<<",I am new thread,pid:"<<getpid()<<",mypthread id:"<<ToHex(pthread_self())<<",cnt:"<<cnt<<endl;
// // //         sleep(1);
// // //         cnt--;
// // //     }
// // //     return nullptr;
// // // }
// // // int main()
// // // {
// // //     pthread_t tid;
// // //     pthread_create(&tid,nullptr,threadrun,(void*)"thread-1");
// // //     //主线程
// // //     int cnt=10;
// // //     while(cnt)
// // //     {
// // //         cout<<"new thread id:"<<ToHex(tid)<<"I am main thread,pid:"<<getpid()<<",mypthread id:"<<ToHex(pthread_self())<<",cnt:"<<cnt<<endl;
// // //         sleep(1);
// // //         cnt--;
// // //     }
// // //     return 0;
// // // }
// // //线程退出
// // //1.代码跑完。结果对
// // //2.代码跑完。结果错
// // //3.异常 一个线程出现问题，其他全部线程都会受到影响，都会导致进程退出
// // int g_val=100;
// // void* threadrun(void* arg)
// // {
// //     std::string thread_name=(char*)arg;
// //     int cnt=5;
// //     while(cnt)
// //     {
// //         cout<<"thread name:"<<thread_name<<",I am new thread,pid:"<<getpid()<<",mypthread id:"<<ToHex(pthread_self())<<",cnt:"<<cnt<<endl;
// //         cout<<"g_val:"<<g_val<<"&g_val:"<<&g_val<<endl;
// //         g_val++;
// //         sleep(1);
// //         cnt--;
// //     }
// //     return (void*)123;
// //     //exit(123);//n=不能使用exit终止线程，只能使用pthread_exit
// //     //pthread_exit((void*)123);
// // }
// // //主线程退出==进程退出==所有进程线程退出
// // //1.我们要保证main Thread最后退出

// // int main()
// // {
// //     pthread_t tid;
// //     pthread_create(&tid,nullptr,threadrun,(void*)"thread-1");
// //     sleep(2);//等待新线程创建完成
// //     pthread_cancel(tid);//取消新线程
// //     //主线程
// //     int cnt=3;
// //     while(cnt)
// //     {
// //         cout<<"new thread id:"<<ToHex(tid)<<"I am main thread,pid:"<<getpid()<<",mypthread id:"<<ToHex(pthread_self())<<",cnt:"<<cnt<<endl;
// //         cout<<"g_val:"<<g_val<<"&g_val:"<<&g_val<<endl;
// //         sleep(1);
// //         cnt--;
// //     }
// //     void* ret=nullptr;
// //     int n=pthread_join(tid,&ret);//线程等待
// //     cout<<"main thread exit,n:"<<n<<",ret:"<<(long long)ret<<endl;
// //     sleep(5);
// //     return 0;
// // }

#include <iostream>
#include <string>
#include <vector>
#include <cstdio>
#include <unistd.h>
#include <cstdlib>
#include <pthread.h> // 原生线程库的头文件

const int threadnum = 5;

class Task
{
public:
    Task()
    {}
    void SetData(int x, int y)
    {
        datax = x;
        datay = y;
    }
    int Excute()
    {
        return datax + datay;
    }
    ~Task()
    {

    }
private:
    int datax;
    int datay;
};

class ThreadData : public Task
{
public:
    ThreadData(int x, int y, const std::string &threadname):_threadname(threadname)
    {
        _t.SetData(x, y);
    }
    std::string threadname()
    {
        return _threadname;
    }
    int run()
    {
        return _t.Excute();
    }
private:
    std::string _threadname;
    Task _t;
};

class Result
{
public:
    Result(){}
    ~Result(){}
    void SetResult(int result, const std::string &threadname)
    {
        _result = result;
        _threadname = threadname;
    }
    void Print()
    {
        std::cout << _threadname << " : " << _result << std::endl;
    }
private:
    int _result;
    std::string _threadname;
};

void *handlerTask(void *args)
{
    ThreadData *td = static_cast<ThreadData *>(args);

    std::string name = td->threadname();

    Result *res = new Result();
    int result = td->run();

    res->SetResult(result, name);

    // std::cout << name << "run result : " << result << std::endl;
    delete td;

    sleep(2);
    return res;
    // // std::string threadname =static_cast<char*>(args);
    // const char *threadname = static_cast<char *>(args);
    // while (true)
    // {
    //     std::cout << "I am " << threadname << std::endl;
    //     sleep(2);
    // }

    // delete []threadname;

    // return nullptr;
}
// 1. 多线程创建
// 2. 线程传参和返回值，我们可以传递级别信息，也可以传递其他对象(包括你自己定义的！)
// 3. C++11也带了多线程，和我们今天的是什么关系？？？ TODO下节课
int main()
{
    std::vector<pthread_t> threads;
    for (int i = 0; i < threadnum; i++)
    {
        char threadname[64];
        snprintf(threadname, 64, "Thread-%d", i + 1);
        ThreadData *td = new ThreadData(10, 20, threadname);

        pthread_t tid;
        pthread_create(&tid, nullptr, handlerTask, td);
        threads.push_back(tid);
    }
    std::vector<Result*> result_set;
    void *ret = nullptr;
    for (auto &tid : threads)
    {
        pthread_join(tid, &ret);
        result_set.push_back((Result*)ret);
    }

    for(auto & res : result_set)
    {
        res->Print();
        delete res;
    }
}